| Conditions | 42 |
| Paths | > 20000 |
| Total Lines | 437 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like ajax.js ➔ ... ➔ jQuery.extend.ajax often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | define( [ |
||
| 386 | ajax: function( url, options ) { |
||
| 387 | |||
| 388 | // If url is an object, simulate pre-1.5 signature |
||
| 389 | if ( typeof url === "object" ) { |
||
| 390 | options = url; |
||
| 391 | url = undefined; |
||
| 392 | } |
||
| 393 | |||
| 394 | // Force options to be an object |
||
| 395 | options = options || {}; |
||
| 396 | |||
| 397 | var transport, |
||
| 398 | |||
| 399 | // URL without anti-cache param |
||
| 400 | cacheURL, |
||
| 401 | |||
| 402 | // Response headers |
||
| 403 | responseHeadersString, |
||
| 404 | responseHeaders, |
||
| 405 | |||
| 406 | // timeout handle |
||
| 407 | timeoutTimer, |
||
| 408 | |||
| 409 | // Url cleanup var |
||
| 410 | urlAnchor, |
||
| 411 | |||
| 412 | // Request state (becomes false upon send and true upon completion) |
||
| 413 | completed, |
||
| 414 | |||
| 415 | // To know if global events are to be dispatched |
||
| 416 | fireGlobals, |
||
| 417 | |||
| 418 | // Loop variable |
||
| 419 | i, |
||
| 420 | |||
| 421 | // uncached part of the url |
||
| 422 | uncached, |
||
| 423 | |||
| 424 | // Create the final options object |
||
| 425 | s = jQuery.ajaxSetup( {}, options ), |
||
| 426 | |||
| 427 | // Callbacks context |
||
| 428 | callbackContext = s.context || s, |
||
| 429 | |||
| 430 | // Context for global events is callbackContext if it is a DOM node or jQuery collection |
||
| 431 | globalEventContext = s.context && |
||
| 432 | ( callbackContext.nodeType || callbackContext.jquery ) ? |
||
| 433 | jQuery( callbackContext ) : |
||
| 434 | jQuery.event, |
||
| 435 | |||
| 436 | // Deferreds |
||
| 437 | deferred = jQuery.Deferred(), |
||
| 438 | completeDeferred = jQuery.Callbacks( "once memory" ), |
||
| 439 | |||
| 440 | // Status-dependent callbacks |
||
| 441 | statusCode = s.statusCode || {}, |
||
| 442 | |||
| 443 | // Headers (they are sent all at once) |
||
| 444 | requestHeaders = {}, |
||
| 445 | requestHeadersNames = {}, |
||
| 446 | |||
| 447 | // Default abort message |
||
| 448 | strAbort = "canceled", |
||
| 449 | |||
| 450 | // Fake xhr |
||
| 451 | jqXHR = { |
||
| 452 | readyState: 0, |
||
| 453 | |||
| 454 | // Builds headers hashtable if needed |
||
| 455 | getResponseHeader: function( key ) { |
||
| 456 | var match; |
||
| 457 | if ( completed ) { |
||
| 458 | if ( !responseHeaders ) { |
||
| 459 | responseHeaders = {}; |
||
| 460 | while ( ( match = rheaders.exec( responseHeadersString ) ) ) { |
||
| 461 | responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; |
||
| 462 | } |
||
| 463 | } |
||
| 464 | match = responseHeaders[ key.toLowerCase() ]; |
||
| 465 | } |
||
| 466 | return match == null ? null : match; |
||
| 467 | }, |
||
| 468 | |||
| 469 | // Raw string |
||
| 470 | getAllResponseHeaders: function() { |
||
| 471 | return completed ? responseHeadersString : null; |
||
| 472 | }, |
||
| 473 | |||
| 474 | // Caches the header |
||
| 475 | setRequestHeader: function( name, value ) { |
||
| 476 | if ( completed == null ) { |
||
| 477 | name = requestHeadersNames[ name.toLowerCase() ] = |
||
| 478 | requestHeadersNames[ name.toLowerCase() ] || name; |
||
| 479 | requestHeaders[ name ] = value; |
||
| 480 | } |
||
| 481 | return this; |
||
| 482 | }, |
||
| 483 | |||
| 484 | // Overrides response content-type header |
||
| 485 | overrideMimeType: function( type ) { |
||
| 486 | if ( completed == null ) { |
||
| 487 | s.mimeType = type; |
||
| 488 | } |
||
| 489 | return this; |
||
| 490 | }, |
||
| 491 | |||
| 492 | // Status-dependent callbacks |
||
| 493 | statusCode: function( map ) { |
||
| 494 | var code; |
||
| 495 | if ( map ) { |
||
| 496 | if ( completed ) { |
||
| 497 | |||
| 498 | // Execute the appropriate callbacks |
||
| 499 | jqXHR.always( map[ jqXHR.status ] ); |
||
| 500 | } else { |
||
| 501 | |||
| 502 | // Lazy-add the new callbacks in a way that preserves old ones |
||
| 503 | for ( code in map ) { |
||
| 504 | statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; |
||
| 505 | } |
||
| 506 | } |
||
| 507 | } |
||
| 508 | return this; |
||
| 509 | }, |
||
| 510 | |||
| 511 | // Cancel the request |
||
| 512 | abort: function( statusText ) { |
||
| 513 | var finalText = statusText || strAbort; |
||
| 514 | if ( transport ) { |
||
| 515 | transport.abort( finalText ); |
||
| 516 | } |
||
| 517 | done( 0, finalText ); |
||
| 518 | return this; |
||
| 519 | } |
||
| 520 | }; |
||
| 521 | |||
| 522 | // Attach deferreds |
||
| 523 | deferred.promise( jqXHR ); |
||
| 524 | |||
| 525 | // Add protocol if not provided (prefilters might expect it) |
||
| 526 | // Handle falsy url in the settings object (#10093: consistency with old signature) |
||
| 527 | // We also use the url parameter if available |
||
| 528 | s.url = ( ( url || s.url || location.href ) + "" ) |
||
| 529 | .replace( rprotocol, location.protocol + "//" ); |
||
| 530 | |||
| 531 | // Alias method option to type as per ticket #12004 |
||
| 532 | s.type = options.method || options.type || s.method || s.type; |
||
| 533 | |||
| 534 | // Extract dataTypes list |
||
| 535 | s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; |
||
| 536 | |||
| 537 | // A cross-domain request is in order when the origin doesn't match the current origin. |
||
| 538 | if ( s.crossDomain == null ) { |
||
| 539 | urlAnchor = document.createElement( "a" ); |
||
| 540 | |||
| 541 | // Support: IE <=8 - 11, Edge 12 - 13 |
||
| 542 | // IE throws exception on accessing the href property if url is malformed, |
||
| 543 | // e.g. http://example.com:80x/ |
||
| 544 | try { |
||
| 545 | urlAnchor.href = s.url; |
||
| 546 | |||
| 547 | // Support: IE <=8 - 11 only |
||
| 548 | // Anchor's host property isn't correctly set when s.url is relative |
||
| 549 | urlAnchor.href = urlAnchor.href; |
||
| 550 | s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== |
||
| 551 | urlAnchor.protocol + "//" + urlAnchor.host; |
||
| 552 | } catch ( e ) { |
||
| 553 | |||
| 554 | // If there is an error parsing the URL, assume it is crossDomain, |
||
| 555 | // it can be rejected by the transport if it is invalid |
||
| 556 | s.crossDomain = true; |
||
| 557 | } |
||
| 558 | } |
||
| 559 | |||
| 560 | // Convert data if not already a string |
||
| 561 | if ( s.data && s.processData && typeof s.data !== "string" ) { |
||
| 562 | s.data = jQuery.param( s.data, s.traditional ); |
||
| 563 | } |
||
| 564 | |||
| 565 | // Apply prefilters |
||
| 566 | inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); |
||
| 567 | |||
| 568 | // If request was aborted inside a prefilter, stop there |
||
| 569 | if ( completed ) { |
||
| 570 | return jqXHR; |
||
| 571 | } |
||
| 572 | |||
| 573 | // We can fire global events as of now if asked to |
||
| 574 | // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) |
||
| 575 | fireGlobals = jQuery.event && s.global; |
||
| 576 | |||
| 577 | // Watch for a new set of requests |
||
| 578 | if ( fireGlobals && jQuery.active++ === 0 ) { |
||
| 579 | jQuery.event.trigger( "ajaxStart" ); |
||
| 580 | } |
||
| 581 | |||
| 582 | // Uppercase the type |
||
| 583 | s.type = s.type.toUpperCase(); |
||
| 584 | |||
| 585 | // Determine if request has content |
||
| 586 | s.hasContent = !rnoContent.test( s.type ); |
||
| 587 | |||
| 588 | // Save the URL in case we're toying with the If-Modified-Since |
||
| 589 | // and/or If-None-Match header later on |
||
| 590 | // Remove hash to simplify url manipulation |
||
| 591 | cacheURL = s.url.replace( rhash, "" ); |
||
| 592 | |||
| 593 | // More options handling for requests with no content |
||
| 594 | if ( !s.hasContent ) { |
||
| 595 | |||
| 596 | // Remember the hash so we can put it back |
||
| 597 | uncached = s.url.slice( cacheURL.length ); |
||
| 598 | |||
| 599 | // If data is available, append data to url |
||
| 600 | if ( s.data ) { |
||
| 601 | cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; |
||
| 602 | |||
| 603 | // #9682: remove data so that it's not used in an eventual retry |
||
| 604 | delete s.data; |
||
| 605 | } |
||
| 606 | |||
| 607 | // Add or update anti-cache param if needed |
||
| 608 | if ( s.cache === false ) { |
||
| 609 | cacheURL = cacheURL.replace( rantiCache, "$1" ); |
||
| 610 | uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; |
||
| 611 | } |
||
| 612 | |||
| 613 | // Put hash and anti-cache on the URL that will be requested (gh-1732) |
||
| 614 | s.url = cacheURL + uncached; |
||
| 615 | |||
| 616 | // Change '%20' to '+' if this is encoded form body content (gh-2658) |
||
| 617 | } else if ( s.data && s.processData && |
||
| 618 | ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { |
||
| 619 | s.data = s.data.replace( r20, "+" ); |
||
| 620 | } |
||
| 621 | |||
| 622 | // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
||
| 623 | if ( s.ifModified ) { |
||
| 624 | if ( jQuery.lastModified[ cacheURL ] ) { |
||
| 625 | jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); |
||
| 626 | } |
||
| 627 | if ( jQuery.etag[ cacheURL ] ) { |
||
| 628 | jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); |
||
| 629 | } |
||
| 630 | } |
||
| 631 | |||
| 632 | // Set the correct header, if data is being sent |
||
| 633 | if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { |
||
| 634 | jqXHR.setRequestHeader( "Content-Type", s.contentType ); |
||
| 635 | } |
||
| 636 | |||
| 637 | // Set the Accepts header for the server, depending on the dataType |
||
| 638 | jqXHR.setRequestHeader( |
||
| 639 | "Accept", |
||
| 640 | s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? |
||
| 641 | s.accepts[ s.dataTypes[ 0 ] ] + |
||
| 642 | ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : |
||
| 643 | s.accepts[ "*" ] |
||
| 644 | ); |
||
| 645 | |||
| 646 | // Check for headers option |
||
| 647 | for ( i in s.headers ) { |
||
| 648 | jqXHR.setRequestHeader( i, s.headers[ i ] ); |
||
| 649 | } |
||
| 650 | |||
| 651 | // Allow custom headers/mimetypes and early abort |
||
| 652 | if ( s.beforeSend && |
||
| 653 | ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { |
||
| 654 | |||
| 655 | // Abort if not done already and return |
||
| 656 | return jqXHR.abort(); |
||
| 657 | } |
||
| 658 | |||
| 659 | // Aborting is no longer a cancellation |
||
| 660 | strAbort = "abort"; |
||
| 661 | |||
| 662 | // Install callbacks on deferreds |
||
| 663 | completeDeferred.add( s.complete ); |
||
| 664 | jqXHR.done( s.success ); |
||
| 665 | jqXHR.fail( s.error ); |
||
| 666 | |||
| 667 | // Get transport |
||
| 668 | transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); |
||
| 669 | |||
| 670 | // If no transport, we auto-abort |
||
| 671 | if ( !transport ) { |
||
| 672 | done( -1, "No Transport" ); |
||
| 673 | } else { |
||
| 674 | jqXHR.readyState = 1; |
||
| 675 | |||
| 676 | // Send global event |
||
| 677 | if ( fireGlobals ) { |
||
| 678 | globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); |
||
| 679 | } |
||
| 680 | |||
| 681 | // If request was aborted inside ajaxSend, stop there |
||
| 682 | if ( completed ) { |
||
| 683 | return jqXHR; |
||
| 684 | } |
||
| 685 | |||
| 686 | // Timeout |
||
| 687 | if ( s.async && s.timeout > 0 ) { |
||
| 688 | timeoutTimer = window.setTimeout( function() { |
||
| 689 | jqXHR.abort( "timeout" ); |
||
| 690 | }, s.timeout ); |
||
| 691 | } |
||
| 692 | |||
| 693 | try { |
||
| 694 | completed = false; |
||
| 695 | transport.send( requestHeaders, done ); |
||
| 696 | } catch ( e ) { |
||
| 697 | |||
| 698 | // Rethrow post-completion exceptions |
||
| 699 | if ( completed ) { |
||
| 700 | throw e; |
||
| 701 | } |
||
| 702 | |||
| 703 | // Propagate others as results |
||
| 704 | done( -1, e ); |
||
| 705 | } |
||
| 706 | } |
||
| 707 | |||
| 708 | // Callback for when everything is done |
||
| 709 | function done( status, nativeStatusText, responses, headers ) { |
||
| 710 | var isSuccess, success, error, response, modified, |
||
| 711 | statusText = nativeStatusText; |
||
| 712 | |||
| 713 | // Ignore repeat invocations |
||
| 714 | if ( completed ) { |
||
| 715 | return; |
||
| 716 | } |
||
| 717 | |||
| 718 | completed = true; |
||
| 719 | |||
| 720 | // Clear timeout if it exists |
||
| 721 | if ( timeoutTimer ) { |
||
| 722 | window.clearTimeout( timeoutTimer ); |
||
| 723 | } |
||
| 724 | |||
| 725 | // Dereference transport for early garbage collection |
||
| 726 | // (no matter how long the jqXHR object will be used) |
||
| 727 | transport = undefined; |
||
| 728 | |||
| 729 | // Cache response headers |
||
| 730 | responseHeadersString = headers || ""; |
||
| 731 | |||
| 732 | // Set readyState |
||
| 733 | jqXHR.readyState = status > 0 ? 4 : 0; |
||
| 734 | |||
| 735 | // Determine if successful |
||
| 736 | isSuccess = status >= 200 && status < 300 || status === 304; |
||
| 737 | |||
| 738 | // Get response data |
||
| 739 | if ( responses ) { |
||
| 740 | response = ajaxHandleResponses( s, jqXHR, responses ); |
||
| 741 | } |
||
| 742 | |||
| 743 | // Convert no matter what (that way responseXXX fields are always set) |
||
| 744 | response = ajaxConvert( s, response, jqXHR, isSuccess ); |
||
| 745 | |||
| 746 | // If successful, handle type chaining |
||
| 747 | if ( isSuccess ) { |
||
| 748 | |||
| 749 | // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
||
| 750 | if ( s.ifModified ) { |
||
| 751 | modified = jqXHR.getResponseHeader( "Last-Modified" ); |
||
| 752 | if ( modified ) { |
||
| 753 | jQuery.lastModified[ cacheURL ] = modified; |
||
| 754 | } |
||
| 755 | modified = jqXHR.getResponseHeader( "etag" ); |
||
| 756 | if ( modified ) { |
||
| 757 | jQuery.etag[ cacheURL ] = modified; |
||
| 758 | } |
||
| 759 | } |
||
| 760 | |||
| 761 | // if no content |
||
| 762 | if ( status === 204 || s.type === "HEAD" ) { |
||
| 763 | statusText = "nocontent"; |
||
| 764 | |||
| 765 | // if not modified |
||
| 766 | } else if ( status === 304 ) { |
||
| 767 | statusText = "notmodified"; |
||
| 768 | |||
| 769 | // If we have data, let's convert it |
||
| 770 | } else { |
||
| 771 | statusText = response.state; |
||
| 772 | success = response.data; |
||
| 773 | error = response.error; |
||
| 774 | isSuccess = !error; |
||
| 775 | } |
||
| 776 | } else { |
||
| 777 | |||
| 778 | // Extract error from statusText and normalize for non-aborts |
||
| 779 | error = statusText; |
||
| 780 | if ( status || !statusText ) { |
||
| 781 | statusText = "error"; |
||
| 782 | if ( status < 0 ) { |
||
| 783 | status = 0; |
||
| 784 | } |
||
| 785 | } |
||
| 786 | } |
||
| 787 | |||
| 788 | // Set data for the fake xhr object |
||
| 789 | jqXHR.status = status; |
||
| 790 | jqXHR.statusText = ( nativeStatusText || statusText ) + ""; |
||
| 791 | |||
| 792 | // Success/Error |
||
| 793 | if ( isSuccess ) { |
||
| 794 | deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); |
||
| 795 | } else { |
||
| 796 | deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); |
||
| 797 | } |
||
| 798 | |||
| 799 | // Status-dependent callbacks |
||
| 800 | jqXHR.statusCode( statusCode ); |
||
| 801 | statusCode = undefined; |
||
| 802 | |||
| 803 | if ( fireGlobals ) { |
||
| 804 | globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", |
||
| 805 | [ jqXHR, s, isSuccess ? success : error ] ); |
||
| 806 | } |
||
| 807 | |||
| 808 | // Complete |
||
| 809 | completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); |
||
| 810 | |||
| 811 | if ( fireGlobals ) { |
||
| 812 | globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); |
||
| 813 | |||
| 814 | // Handle the global AJAX counter |
||
| 815 | if ( !( --jQuery.active ) ) { |
||
| 816 | jQuery.event.trigger( "ajaxStop" ); |
||
| 817 | } |
||
| 818 | } |
||
| 819 | } |
||
| 820 | |||
| 821 | return jqXHR; |
||
| 822 | }, |
||
| 823 | |||
| 856 |